package com.wande.dataplatform.filecollection.validation;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.wande.dataplatform.filecollection.domain.MappingRule;
import com.wande.dataplatform.filecollection.domain.dto.FieldValidationRule;
import com.wande.dataplatform.filecollection.domain.dto.ValidationError;
import com.wande.dataplatform.filecollection.domain.dto.ValidationResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 校验服务
 * 提供数据质量校验功能
 *
 * @author wande
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ValidationService {

    private final ValidationRuleRegistry ruleRegistry;

    /**
     * 校验单条记录
     *
     * @param record 记录数据
     * @param mappingRule 映射规则（包含校验规则配置）
     * @return 校验结果
     */
    public ValidationResult validateRecord(Map<String, Object> record, MappingRule mappingRule) {
        return validateRecord(record, mappingRule, null);
    }

    /**
     * 校验单条记录
     *
     * @param record 记录数据
     * @param mappingRule 映射规则
     * @param recordIndex 记录索引
     * @return 校验结果
     */
    public ValidationResult validateRecord(Map<String, Object> record, MappingRule mappingRule, Integer recordIndex) {
        ValidationResult result = ValidationResult.success();

        // 解析校验规则
        List<FieldValidationRule> validationRules = parseValidationRules(mappingRule);
        if (CollUtil.isEmpty(validationRules)) {
            return result;
        }

        // 执行校验
        for (FieldValidationRule rule : validationRules) {
            // 跳过未启用的规则
            if (Boolean.FALSE.equals(rule.getEnabled())) {
                continue;
            }

            String fieldName = rule.getFieldName();
            Object fieldValue = record.get(fieldName);

            // 获取校验规则实例
            IValidationRule validationRule = ruleRegistry.getRule(rule.getRuleType());
            if (validationRule == null) {
                log.warn("未找到校验规则: {}", rule.getRuleType());
                continue;
            }

            // 执行校验
            ValidationError error = validationRule.validate(fieldName, fieldValue, rule.getRuleConfig());
            if (error != null) {
                // 转换为ValidationResult.ValidationError
                result.addError(ValidationResult.ValidationError.builder()
                    .fieldName(error.getFieldName())
                    .errorType(error.getRuleType())
                    .errorMessage(error.getErrorMessage())
                    .fieldValue(error.getFieldValue())
                    .build());
            }
        }

        return result;
    }

    /**
     * 批量校验记录
     *
     * @param records 记录列表
     * @param mappingRule 映射规则
     * @return 校验结果列表
     */
    public List<ValidationResult> validateRecords(List<Map<String, Object>> records, MappingRule mappingRule) {
        List<ValidationResult> results = new ArrayList<>();
        
        for (int i = 0; i < records.size(); i++) {
            ValidationResult result = validateRecord(records.get(i), mappingRule, i);
            results.add(result);
        }

        return results;
    }

    /**
     * 批量校验并生成统计信息
     *
     * @param records 记录列表
     * @param mappingRule 映射规则
     * @return 校验统计信息
     */
    public com.wande.dataplatform.filecollection.domain.dto.ValidationStatistics validateAndAnalyze(
            List<Map<String, Object>> records, MappingRule mappingRule) {
        
        com.wande.dataplatform.filecollection.domain.dto.ValidationStatistics statistics = 
            com.wande.dataplatform.filecollection.domain.dto.ValidationStatistics.builder()
                .totalRecords((long) records.size())
                .validRecords(0L)
                .invalidRecords(0L)
                .build();

        for (int i = 0; i < records.size(); i++) {
            ValidationResult result = validateRecord(records.get(i), mappingRule, i);
            
            if (result.getValid()) {
                statistics.setValidRecords(statistics.getValidRecords() + 1);
            } else {
                statistics.setInvalidRecords(statistics.getInvalidRecords() + 1);
                
                // 统计错误类型和字段
                for (ValidationResult.ValidationError error : result.getErrors()) {
                    statistics.incrementErrorType(error.getErrorType());
                    statistics.incrementFieldError(error.getFieldName());
                }
            }
        }

        statistics.calculatePassRate();
        return statistics;
    }

    /**
     * 校验规则配置是否有效
     *
     * @param ruleType 规则类型
     * @param ruleConfig 规则配置
     * @return 是否有效
     */
    public boolean isValidRuleConfig(String ruleType, String ruleConfig) {
        IValidationRule rule = ruleRegistry.getRule(ruleType);
        if (rule == null) {
            return false;
        }
        return rule.isValidConfig(ruleConfig);
    }

    /**
     * 解析校验规则配置
     */
    private List<FieldValidationRule> parseValidationRules(MappingRule mappingRule) {
        if (mappingRule == null || mappingRule.getValidationRules() == null) {
            return new ArrayList<>();
        }

        try {
            return JSONUtil.toList(mappingRule.getValidationRules(), FieldValidationRule.class);
        } catch (Exception e) {
            log.error("解析校验规则配置失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取所有可用的校验规则类型
     *
     * @return 规则类型列表
     */
    public List<String> getAvailableRuleTypes() {
        return ruleRegistry.getAllRuleTypes();
    }
}
